package com.jzo2o.orders.manager.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.hutool.db.DbRuntimeException;
import com.jzo2o.api.customer.AddressBookApi;
import com.jzo2o.api.customer.dto.response.AddressBookResDTO;
import com.jzo2o.api.foundations.ServeApi;
import com.jzo2o.api.foundations.dto.response.ServeAggregationResDTO;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.utils.DateUtils;
import com.jzo2o.common.utils.NumberUtils;
import com.jzo2o.mvc.utils.UserContext;
import com.jzo2o.orders.base.enums.OrderPayStatusEnum;
import com.jzo2o.orders.base.mapper.OrdersMapper;
import com.jzo2o.orders.base.model.domain.Orders;
import com.jzo2o.orders.manager.model.dto.request.PlaceOrderReqDTO;
import com.jzo2o.orders.manager.model.dto.response.PlaceOrderResDTO;
import com.jzo2o.orders.manager.service.IOrdersCreateService;
import com.jzo2o.orders.manager.service.client.CustomerClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import static com.jzo2o.orders.base.constants.RedisConstants.Lock.ORDERS_SHARD_KEY_ID_GENERATOR;

/**
 * <p>
 * 下单服务类
 * </p>
 *
 * @author ithyfjs
 * @since 2024-07-10
 */
@Slf4j
@Service
public class OrdersCreateServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersCreateService {

    @Resource
    private ServeApi serveApi;

    @Resource
    private AddressBookApi addressBookApi;

    @Resource
    private IOrdersCreateService owner;

    @Resource
    private CustomerClient customerClient;

    @Resource
    private RedisTemplate<String, Long> redisTemplate;
    /**
     * 生成订单id 格式：{yyMMdd}{13位id}
     *
     * @return
     */
    private Long generateOrderId() {
        //通过Redis自增序列得到序号
        Long id = redisTemplate.opsForValue().increment(ORDERS_SHARD_KEY_ID_GENERATOR, 1);
        //生成订单号   2位年+2位月+2位日+13位序号
        long orderId = DateUtils.getFormatDate(LocalDateTime.now(), "yyMMdd") * 10000000000000L + id;
        return orderId;
    }

    @Override
    public PlaceOrderResDTO placeOrder(PlaceOrderReqDTO placeOrderReqDTO) {
        // 1.数据校验
        // 校验服务地址
        AddressBookResDTO detail = customerClient.getDetail(placeOrderReqDTO.getAddressBookId());
        if (detail == null) {
            throw new BadRequestException("预约地址异常，无法下单");
        }
        // 服务
        ServeAggregationResDTO serveResDTO = serveApi.findById(placeOrderReqDTO.getServeId());
        System.out.println("serveResDTO:"+serveResDTO);
        //服务下架不可下单
        if (serveResDTO == null || serveResDTO.getSaleStatus() != 2) {
            throw new BadRequestException("服务不可用");
        }

        // 2.下单前数据准备(对照数据库表一个个写)
        Orders orders = new Orders();
        // 设置订单id
        orders.setId(generateOrderId());
        // 设置用户ID
        orders.setUserId(UserContext.currentUserId());
        // 设置服务id
        orders.setServeId(placeOrderReqDTO.getServeId());
        // 设置服务项id/名称/图片/单位
        orders.setServeItemId(serveResDTO.getServeItemId());
        orders.setServeItemName(serveResDTO.getServeItemName());
        orders.setServeItemImg(serveResDTO.getServeItemImg());
        orders.setUnit(serveResDTO.getUnit());
        // 设置服务类型id/名称
        orders.setServeTypeId(serveResDTO.getServeTypeId());
        orders.setServeTypeName(serveResDTO.getServeTypeName());
        // 设置订单状态
        orders.setOrdersStatus(0);
        // 设置支付状态
        orders.setPayStatus(2);
        // 设置单价
        orders.setPrice(serveResDTO.getPrice());
        // 设置购买数量
        orders.setPurNum(placeOrderReqDTO.getPurNum());
        // 设置总价：单价*数量
        orders.setTotalAmount(serveResDTO.getPrice().multiply(new BigDecimal(placeOrderReqDTO.getPurNum())));
        // 设置优惠金额 TODO
        orders.setDiscountAmount(BigDecimal.ZERO);
        // 设置实付金额：总价-优惠金额
        orders.setRealPayAmount(NumberUtils.sub(orders.getTotalAmount(), orders.getDiscountAmount()));
        // 设置城市编码
        orders.setCityCode(serveResDTO.getCityCode());
        // 设置服务详细地址
        String address = new StringBuffer(detail.getProvince())
                .append(detail.getCity())
                .append(detail.getCounty())
                .append(detail.getAddress())
                .toString();
        orders.setServeAddress(address);
        // 设置联系手机号
        orders.setContactsPhone(detail.getPhone());
        // 设置联系人
        orders.setContactsName(detail.getName());
        // 设置服务预约时间
        orders.setServeStartTime(placeOrderReqDTO.getServeStartTime());
        // 设置经纬度
        orders.setLon(detail.getLon());
        orders.setLat(detail.getLat());
        // 设置排序的sortBy字段
        orders.setSortBy(DateUtils.toEpochMilli(orders.getServeStartTime()) + orders.getId() % 100000);
        //保存订单
        owner.add(orders);

        return new PlaceOrderResDTO(orders.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(Orders orders) {
        boolean save = this.save(orders);
        if (!save) {
            throw new DbRuntimeException("下单失败");
        }
    }
}
